/**
 * 文件：CommentService.java
 * 作者：赵子樵
 * 完成度：完成
 * 最后修改日期：2023-7-1 01:22
 */

package com.gomokult.service;

import java.util.List;
import com.gomokult.entity.Comment;
import com.gomokult.exception.InvalidIDException;
import com.gomokult.exception.NoSuchPageException;
import com.gomokult.exception.IllegalOperationException;

/**
 * 提供与评论相关的服务接口。
 * @author 赵子樵
 */
public interface CommentService {
	/**
	 * 根据评论ID获取其对应的{@code Comment}实体。
	 * @param commentID 需要查询的评论的ID字段
	 * @return ID为{@code commentID}的持久化对象
	 * @throws InvalidIDException 当ID无效或不存在时
	 */
	Comment getComment(int commentID) throws InvalidIDException;

	/**
	 * 获取ID为{@code gameID}的对局下所有评论的数量。
	 * @param gameID 待查询对局的ID
	 * @return 一个整数，表示评论的总数
	 * @throws InvalidIDException 当ID无效或不存在时
	 */
	int getCommentsCount(int gameID) throws InvalidIDException;
	
	/**
	 * 获取ID为{@code gameID}的对局下用户评论的总页数（每页最多显示二十条评论）。
	 * @param gameID 待查询对局的ID
	 * @return 一个整数，表示评论的总页数
	 * @throws InvalidIDException 当ID无效或不存在时
	 */
	int getCommentPagesCount(int gameID) throws InvalidIDException;

	/**
	 * 获取ID为{@code gameID}的对局下第{@code page}页的所有评论，评论按照发布时间倒序排列，每页最多显示二十条评论。
	 * @param gameID 待查询对局的ID
	 * @param page 待查询评论页的页号，以1为起始页号
	 * @return 该页评论的有序列表（按照评论时间倒序排列）
	 * @throws InvalidIDException 当ID无效或不存在时
	 * @throws NoSuchPageException 当不存在页号为{@code page}的页面时
	 */
	List<Comment> getCommentsFromPage(int gameID, int page) throws InvalidIDException, NoSuchPageException;

	/**
	 * 以用户{@code userID}的身份删除评论{@code commentID}。对于合法的{@code commentID}，若{@code userID}为该评论所处对局的参与者，此方法应当总是执行成功；在其它一般情况下，用户只能删除自己所发表的评论，否则抛出{@code IllegalOperationException}。<p>
	 * @param userID 欲执行删除操作的用户ID
	 * @param commentID 需要被删除的评论ID
	 * @throws InvalidIDException 当ID无效或不存在时
	 * @throws IllegalOperationException 当用户不具备删除目标评论的能力时
	 */
	void deleteComment(int userID, int commentID) throws InvalidIDException, IllegalOperationException;

	/**
	 * 以用户{@code userID}的身份清除对局{@code gameID}下的所有评论。对于合法的{@code gameID}，若ID为{@code userID}的用户为该对局的参与者，此方法应当总是执行成功，否则抛出{@code IllegalOperationException}。<p>
	 * @param userID 欲执行清除操作的用户ID
	 * @param gameID 需要被清空评论区的对局ID
	 * @throws InvalidIDException 当ID无效或不存在时
	 * @throws IllegalOperationException 当用户不具备清空评论区的能力时
	 */
	void clearComment(int userID, int gameID) throws InvalidIDException, IllegalOperationException;

	/**
	 * 以用户{@code userID}的身份在{@code gameID}对局下发表一段内容为{@code content}的评论，发布时间等附加参数在运行时根据当前上下文自动获取。如果指定了{@code parentID}参数，则将{@code parentID}作为其父评论，以实现“回复评论”的效果。<p>
	 * 用例：
	 * <li>1. {@code replyComment(user, game, "Hello World!", 0);} - 用户'user'在'game'对局下发表了评论"Hello World!"
	 * <li>2. {@code replyComment(user, game, "Hello World!", par);} - 用户'user'在'game'对局下回复了评论'par'，回复内容为"Hello World!"
	 * @param userID 发布评论的用户ID
	 * @param gameID 用户所评论的对局ID
	 * @param content 评论内容
	 * @param parentID 父级评论ID。当值为{@code 0}时，表示无父评论，即直接发布在评论区中的新评论；当值为合法的主键ID时，若目标ID所代表的评论也处于对局{@code gameID}的评论区下时，将{@code parentID}作为其父评论；否则，触发{@code InvalidIDException}
	 * @param referencedRounds 评论所引用的局面。特别的，当值为{@code 0}时，表示不对局面进行引用
	 * @return 一个整数，表示数据库为该评论分配的ID
	 * @throws InvalidIDException 当ID无效或不存在时
	 */
	int publishComment(int userID, int gameID, String content, int parentID, int referencedRounds) throws InvalidIDException;
	
	/**
	 * 以用户{@code userID}的身份在{@code gameID}对局下发表一段内容为{@code content}的评论，发布时间等附加参数在运行时根据当前上下文自动获取。<p>
	 * * 等价于{@code publishComment(user, game, content, 0);}
	 * @param userID 发布评论的用户ID
	 * @param gameID 用户所评论的对局ID
	 * @param content 评论内容
	 * @return 一个整数，表示数据库为该评论分配的ID
	 * @throws InvalidIDException 当ID无效或不存在时
	 */
	int publishComment(int userID, int gameID, String content) throws InvalidIDException;
	
	/**
	 * 以用户{@code userID}的身份设置对局{@code gameID}是否允许用户发表评论（包括设置者自己）。对于表中存在的{@code userID}与{@code gameID}，若用户为该对局的参与者，则该方法应总是成功；否则抛出{@code IllegalOperationException}。
	 * #deprecated 该方法已弃用，或被暂时搁置
	 * @param userID 欲设置评论权限的用户ID
	 * @param gameID 需要设置评论权限的对局ID
	 * @param commentable 一个布尔值，表示该对局的评论区是否开放
	 * @throws InvalidIDException 当ID无效或不存在时
	 * @throws IllegalOperationException 当用户不具备配置评论区的权限时
	 */
	// void setCommentable(int userID, int gameID, boolean commentable) throws InvalidIDException, IllegalOperationException;
	
	/**
	 * 查询ID为{@code gameID}的对局是否允许用户发表评论，即该对局的评论区是否开放。
	 * #deprecated 该方法已弃用，或被暂时搁置
	 * @param gameID 待查询的对局ID
	 * @return 一个布尔值，表示该对局的评论区是否开放
	 * @throws InvalidIDException 当ID无效或不存在时
	 */
	// boolean getCommentable(int gameID) throws InvalidIDException;
}
